﻿       
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace Organized
{
    public class Grid : Component, I3DComponent
    {

        Effect gridEffect;
        Texture2D displacementTexture;
        Camera camera;

        public Grid(Effect effect,Texture2D texture, Camera cam, GameScreen Parent):base(Parent)
        {
            camera = cam;
            LoadGraphicsContent();
            gridEffect = effect;
            displacementTexture = texture;
            LoadGraphicsContent();
        }
    
        GraphicsDevice device;
        VertexBuffer vb;
        IndexBuffer ib;
        VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[4];
        int[] indices = new int[6];

        VertexDeclaration vertexDecl;

        private float cellSize = 4;

        public float CellSize
        {
            get { return cellSize; }
            set { cellSize = value; }
        }

        private short dimension = 128;

        public short Dimension
        {
            get { return dimension; }
            set { dimension = value; }
        }

        // I3DComponent values
        Vector3 indexPosition = Vector3.Zero;
        Vector3 position = Vector3.Zero;
        Matrix rotation = Matrix.Identity;
        Vector3 scale = new Vector3(1, 1, -1);
        BoundingBox boundingBox = new BoundingBox(new Vector3(-1), new Vector3(1));

        public Vector3 Position { get { return position; } set { position = value; } }
        public Vector3 EulerRotation
        {
            get { return MathUtil.MatrixToVector3(Rotation); }
            set { this.Rotation = MathUtil.Vector3ToMatrix(value); }
        }
        public Matrix Rotation { get { return rotation; } set { rotation = value; } }
        public Vector3 Scale { get { return scale; } set { scale = value; } }
        public BoundingBox BoundingBox { get { return boundingBox; } }


        public void GenerateStructures()
        {

            vertices = new VertexPositionNormalTexture[(dimension + 1) * (dimension + 1)];
            indices = new int[dimension * dimension * 6];
            for (int i = 0; i < dimension + 1; i++)
            {
                for (int j = 0; j < dimension + 1; j++)
                {
                    VertexPositionNormalTexture vert = new VertexPositionNormalTexture();
                    vert.Position = new Vector3((i - dimension / 2.0f) * cellSize, 0, (j - dimension / 2.0f) * cellSize);
                    vert.Normal = Vector3.Up;
                    vert.TextureCoordinate = new Vector2((float)i / dimension, (float)j / dimension);
                    vertices[i * (dimension + 1) + j] = vert;
                }
            }

            for (int i = 0; i < dimension; i++)
            {
                for (int j = 0; j < dimension; j++)
                {
                    indices[6 * (i * dimension + j)] = (i * (dimension + 1) + j);
                    indices[6 * (i * dimension + j) + 1] = (i * (dimension + 1) + j + 1);
                    indices[6 * (i * dimension + j) + 2] = ((i + 1) * (dimension + 1) + j + 1);

                    indices[6 * (i * dimension + j) + 3] = (i * (dimension + 1) + j);
                    indices[6 * (i * dimension + j) + 4] = ((i + 1) * (dimension + 1) + j + 1);
                    indices[6 * (i * dimension + j) + 5] = ((i + 1) * (dimension + 1) + j);
                }

            }

        }

        public void DrawGrid()
        {
           
     
            
            gridEffect.CurrentTechnique = gridEffect.Techniques["GridDraw"];

            gridEffect.Parameters["world"].SetValue(Matrix.Identity);
            gridEffect.Parameters["view"].SetValue(camera.View);
            gridEffect.Parameters["proj"].SetValue(camera.Projection);
            gridEffect.Parameters["maxHeight"].SetValue(128);
            gridEffect.Parameters["displacementMap"].SetValue(displacementTexture);

            device = Engine.GraphicsDevice;


           


            gridEffect.Begin();
            foreach (EffectPass pass in gridEffect.CurrentTechnique.Passes)
            {
                pass.Begin();

                    device.VertexDeclaration = vertexDecl;

                    device.Vertices[0].SetSource(vb, 0, VertexPositionNormalTexture.SizeInBytes);
                    device.Indices = ib;
                    
                    device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, (dimension + 1) * (dimension + 1), 0, 2 * dimension * dimension);


            
                
                pass.End();
            }
            gridEffect.End();

          

        }

        public void LoadGraphicsContent()
        {

            GenerateStructures();

           
            device = Engine.GraphicsDevice;

            vb = new VertexBuffer(Engine.GraphicsDevice, (dimension + 1) * (dimension + 1) * VertexPositionNormalTexture.SizeInBytes, BufferUsage.None);
            ib = new IndexBuffer(Engine.GraphicsDevice, 6 * dimension * dimension * sizeof(int), BufferUsage.None, IndexElementSize.ThirtyTwoBits);
             
            vb.SetData<VertexPositionNormalTexture>(vertices);
            ib.SetData<int>(indices);
            

            vertexDecl = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements);
        }
    }
}



 